﻿/**	\file		canvas.h
 *	\date		(2007-02-10 22:50:33)/(2015-01-28 19:27:07)
 *-----------------------------------------------------------------------------
 *	\brief		画布.
 *	\version	1.0.43.97
 *	\author		Nick Shallery	(nicknide@gmail.com)
 *	\copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)
#define		__LOLIX__PRETTY__CANVAS__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__SOLA__MATRIX__K_IN_G__)
	#include	"../lolix/sola/matrix.h"
#endif	//	!defined(__LOLIX__SOLA__MATRIX__K_IN_G__)
#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix/lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix/lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

namespace lolix{
	namespace sola{
		class dancer;
	}

	namespace loli{
		class file_block;
	}
}

namespace lolix{namespace pretty{
	class	buffer_depth;
	class	canvas;
	class	canvas_package;
	class	canvas_package_factory;
	class	render_material;
	class	render_mesh;
	class	render_params;
	class	render_properties;
	class	render_shader;
	class	render_texture;
	class	vertex_buffer;
	enum	ENUM_IDX_TYPE{IDX_TYPE_ATTR, IDX_TYPE_UNIF, IDX_TYPE_TEX, _IDX_TYPE_CNT, _IDX_TYPE_VER = 0};
	enum	ENUM_SHADER_TYPE{ sd_v = 0, sd_g = 1, sd_f = 2, _sd_cnt, _sd_ver = 3};	//	vertex shader, framge shader
	enum	ENUM_PIXEL_TYPE LOLIX_ETYPE(lx_u32)
	{
		PIXEL_TYPE_UNKNOW			,	//	未知
		PIXEL_TYPE_RED				,
		PIXEL_TYPE_RG				,
		PIXEL_TYPE_BGR				,	//	BGR		- 24 bits.
		PIXEL_TYPE_ABGR				,	//	ABGR	- 32 bits.
		PIXEL_TYPE_RGB				,
		PIXEL_TYPE_ARGB				,

		_PIXEL_TYPE_CNT				,
		_PIXEL_TYPE_VER	= 1			,
	};

	enum ENUM_RENDER_DEVICE_TYPE LOLIX_ETYPE(lx_u32)
	{
		RENDER_DEVICE_TYPE_NULL		,	//
		RENDER_DEVICE_TYPE_DEFAULT	,	//
		RENDER_DEVICE_TYPE_OPENGL	,	//
		RENDER_DEVICE_TYPE_D3D		,	//
	};

	enum	ENUM_USAGE_TYPE LOLIX_ETYPE(lx_u32)
	{
		USAGE_TYPE_OPTION_DRAW		= 0x01	,	//	用来绘制
		USAGE_TYPE_OPTION_READ		= 0x02	,	//	用来读
		USAGE_TYPE_OPTION_COPY		= 0x04	,	//	用来复制

		USAGE_TYPE_STRATEGY_STREAM	= 0x10	,	//	流数据
		USAGE_TYPE_STRATEGY_DYNAMIC	= 0x20	,	//	动态数据
		USAGE_TYPE_STRATEGY_STATIC	= 0x30	,	//	静态数据

		_USAGE_TYPE_BITS_SIZE		= 0x06	,
	};

	struct canvas_startinfo
	{
		enum { _ver = 0 };
		LOLIX_INLINE_CALL void make_init(void){ver = _ver; size = sizeof(*this);}
		lx_u16					ver;			///<	结构体版本.
		lx_u16					size;			///<	sizeof(canvas_startinfo).
		ENUM_RENDER_DEVICE_TYPE	device_type;	///<	设备类型.
		lx_u32					max_work_thread;///<	最大可用线程.
	};
	STATIC_ASSERT(sizeof(canvas_startinfo) == 12);
}}


class LOLIX_NO_VTABLE lolix::pretty::canvas_package_factory
	: public itf
{
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package_factory, lolix::itf, (0x8fb2cd64, 0xeedd406b, 0xaa55c1b7, 0x9e5fd4cd));
public:
	typedef	void*	platform_win_handle;
	LOLIX_INTERFACE(create_inst, LOLIX_RETNV	, (canvas_package** out_ptr, platform_win_handle, canvas_startinfo const* startinfo));
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas_package
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas_package, lolix::itf, (0xc19ef509, 0xcebf40b2, 0xa031016e, 0xdaf9e353));
	LOLIX_DECLARE_PROXY(0x1c7d2e5e, 0x8cb54e7a, 0x936cffe9, 0x0ed1ba51);

	typedef	render_material		r_material;
	typedef	render_mesh			r_mesh;
	typedef	render_properties	r_prop;
	typedef	render_texture		r_tex;
	typedef	render_params		r_params;
	typedef render_shader		r_shader;

	typedef	buffer_depth		b_dep;		//	深度缓冲区

	//LOLIX_INTERFACE_DEPRECATED(set_option		, LOLIX_RETNV, (size_type opt_type, const size_type* param), "use render_properties instander");
	//LOLIX_INTERFACE_DEPRECATED(get_option		, LOLIX_RETNV, (size_type opt_type, size_type* out_ptr)const, "use render_properties instander");
	typedef	union _tagDepthBufferParams
	{
		typedef	lx_u32	flag_type;
		LOLIX_INLINE_CALL	_tagDepthBufferParams(void){}
		LOLIX_INLINE_CALL	_tagDepthBufferParams(flag_type flg):_flag(flg){}
		LOLIX_INLINE_CALL	_tagDepthBufferParams(init_for_nothing_copy){}

		LOLIX_INLINE_CALL	void set_flag(flag_type flg)		{_flag = flg;}
		LOLIX_INLINE_CALL	void set_bits(flag_type bits_size)	{_bits_size = 4 - ((bits_size >> 3) & 0x3);}
		LOLIX_INLINE_CALL	void set_width(flag_type width)		{_width = width;}
		LOLIX_INLINE_CALL	void set_height(flag_type height)	{_height = height;}

		LOLIX_INLINE_CALL	flag_type get_flag(void)const		{return _flag;}
		LOLIX_INLINE_CALL	flag_type get_bits(void)const		{return (4 - _bits_size) << 3;}
		LOLIX_INLINE_CALL	flag_type get_width(void)const		{return _width;}
		LOLIX_INLINE_CALL	flag_type get_height(void)const		{return _height;}

#if			defined(LOLIX_DEF__CC_TYPE_MS)
		__declspec(property(get = get_flag	, put = set_flag))		flag_type	flag;
		__declspec(property(get = get_bits	, put = set_bits))		flag_type	bits;
		__declspec(property(get = get_width	, put = set_width))		flag_type	width;
		__declspec(property(get = get_height, put = set_height))	flag_type	height;
#endif	//	defined(LOLIX_DEF__CC_TYPE_MS)
	private:
__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
		struct
		{
		flag_type	_bits_size	: 2;
		flag_type	_width		:14;
		flag_type	_height		:14;
		flag_type	_reserver	: 2;
		};

		flag_type	_flag;
	}b_deepth_params;
	STATIC_ASSERT(sizeof (b_deepth_params) == sizeof (b_deepth_params::flag_type));

	union spted_flag
	{
		lx_u32 flag;
		struct
		{
			lx_u32 geometry_shader	: 1;
			lx_u32 hardware_stereo	: 1;
		};
	};

	union stereo_type
	{
		struct
		{
			lx_u32	stereo_right_red	: 1;	//	右通道包含红色
			lx_u32	stereo_right_greed	: 1;	//	右通道包含绿色
			lx_u32	stereo_right_blue	: 1;	//	右通道包含蓝色
			lx_u32	stereo_enable		: 1;	//	双通道支持
			lx_u32	stereo_quad			: 1;	//	四通道缓冲
		};
		struct
		{
			lx_u32	stereo_mask			: 3;	//	双通道渲染通道位置
		};
		lx_u32	flag;
	};
__END_DISABLE_NO_NAME_STRUCT_WARNING();
	/**
	* \brief	[开启/关闭]当前线程是否激活渲染上下文.
	* \arg is_active	true:在当前线程激活渲染上下文， false:在当前线程关闭渲染上下文.
	* \return	失败返回 lolix error.
	**/
	LOLIX_INTERFACE(thread_active, LOLIX_RETNV, (bool is_active));

	LOLIX_INTERFACE(query_supported	, spted_flag	, (void)const);

	//	create depth buffer
	LOLIX_INTERFACE(c_bdep	, LOLIX_RETNV	, (buffer_depth**, _tagDepthBufferParams param));
	//	创建一个绘制上下文
	//	depth_buffer_bits : 缓冲区的位数， 16, 24, 32 等， 0 表示不创建默认深度缓冲区
	//LOLIX_INTERFACE(create_canvas	, LOLIX_RETNV	, (canvas** out_ptr, size_type depth_buffer_bits));

	LOLIX_INTERFACE(set_stereo	, LOLIX_RETNV	, (stereo_type st));
	LOLIX_INTERFACE(get_stereo	, stereo_type	, (void)const);

	//===========================================================================
	//	将 canvas 的内容提交到 palette 上面去
	//---------------------------------------------------------------------------
	//	tex			[i ]	:	需要提交的纹理
	//	tex_cnt		[i ]	:	纹理数量, 1 : 表示按照平面渲染提交, 2 表示按照立体(stereo)方式提交
	//							其他为无效值
	//	tex_pos		[i ]	:	为使用渲染平面的  x, y, width, height, 0 表示全部
	//	tex_uv		[i ]	:	为使用 uv 的 x, y, width, height, 0 表示全部
	//===========================================================================
	LOLIX_INTERFACE(submit	, LOLIX_RETNV	, (render_texture** tex, size_type tex_cnt, const lx_u16* tex_pos/* = 0*/, const float* tex_uv /* = 0 */));

	LOLIX_INTERFACE(query_proxy	, void		 , (proxy_type** prx_type));
	LOLIX_INTERFACE(ist_usr_itf	, LOLIX_RETNV, (lolix::itf*, lolix::LOLIX_ITF_ID const* itf_id));
	LOLIX_INTERFACE(get_usr_itf	, LOLIX_RETNV, (lolix::itf**, lolix::LOLIX_ITF_ID const* itf_id)const);
	LOLIX_INTERFACE(clr_usr_itf	, void		 , (lolix::LOLIX_ITF_ID const* itf_id));

	LOLIX_INTERFACE(destroy		, void		 , (void));

	template<typename _Ty>
	LOLIX_INLINE_CALL LOLIX_RETNV ist_usr_itf(_Ty ty)
		{
		const LOLIX_ITF_ID itf_id(LOLIX_ITF_FROM_VAL(*ty));
		return ist_usr_itf(ty, &itf_id);
		}

	template<typename _Ty>
	LOLIX_INLINE_CALL LOLIX_RETNV get_usr_itf(_Ty** ty)const
		{
		const LOLIX_ITF_ID itf_id(LOLIX_ITF_FROM_TYPE(_Ty));
		return get_usr_itf((lolix::itf**)ty, &itf_id);
		}
};


class	LOLIX_NO_VTABLE	lolix::pretty::buffer_depth
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::buffer_depth, lolix::itf, (0x00671d7a, 0x0d2a4052, 0x8232173a, 0x9774ce68));
	typedef	canvas_package::_tagDepthBufferParams	_tagDepthBufferParams;
	typedef	canvas_package::b_deepth_params			b_deepth_params;
	//	得到深度缓冲区的位数
	LOLIX_INTERFACE(get_params	, LOLIX_RETNV	, (_tagDepthBufferParams* out_ptr)const);
};


class	LOLIX_NO_VTABLE	lolix::pretty::canvas
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::canvas, lolix::itf, (0x97f39d4f, 0x324f4fde, 0xb4bea1c4, 0xee080a95));

	enum	ENUM_CANVAS_ELEMENT
	{
		CANVAS_ELEMENT_COLOR	= 1,
		CANVAS_ELEMENT_DEPTH	= 2,
	};

	enum	ENUM_CANVAS_OPTION
	{
		CANVAS_OPTION_VIEWPORT		,	//	io. lx_u32 4 param (x, y, width, height)
	};

	LOLIX_INTERFACE(set_option		, LOLIX_RETNV,	(size_type opt_type, const void* param));
	LOLIX_INTERFACE(get_option		, LOLIX_RETNV,	(size_type opt_type, void* out_ptr)const);

	LOLIX_INTERFACE(set_fragdata	, LOLIX_RETNV,	(render_texture* const* inptr, size_type incnt));
	LOLIX_INTERFACE(get_fragdata	, LOLIX_RETNV,	(render_texture** outptr, size_type from, size_type* iocnt));

	//--------------------------------------------------------------------------
	//	>> 2008-12-03 00:23:02 >>------------------->> 2008-12-03 00:23:02 >>
		//FUNC>>$	:设置渲染上下文的深度缓冲区
			//FUNC>>@0	:[in]	深度缓冲区， 内部会自动调用 inc_ref
			//FUNC>>@1	:[out]	原始的深度缓冲区， 如果该指针为0， 则不会传出原始缓冲区， 此时内部会自动把该对象 release
				//FUNC>>#	:成功则返回 LOLIX_RETNV_OK, 其他状况返回各式失败
	//--------------------------------------------------------------------------
	LOLIX_INTERFACE(set_bdep		, LOLIX_RETNV,	(buffer_depth* dep_buf, buffer_depth** out /* = 0 */));

	//===========================================================================
	//	渲染一组 mesh
	//---------------------------------------------------------------------------
	//	rmat	[i ] :	渲染材质
	//	rmsh	[i ] :	渲染用mesh
	//	rmsh_cnt[i ] :	渲染用的数量
	//===========================================================================
	LOLIX_INTERFACE(render_meshs	, LOLIX_RETNV	, (render_material* rmat, render_mesh** rmsh, size_type rmsh_cnt));
	LOLIX_INTERFACE(clear_cbuf		, LOLIX_RETNV	, (size_type canvas_elemnt, const float* clr_color));
};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:参数， 包含 一套材质对应的常数参数， 可以通过 material 请求出默认的数据
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::render_params
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::render_params, lolix::itf, (0xa9e803b8, 0xd0d542dd, 0xad4cf943, 0xf3f9d16c));

	LOLIX_INTERFACE(set_idx		, LOLIX_RETNV	, (ENUM_IDX_TYPE idx_type, const char* const name[], size_type name_len[], size_type idx[], size_type array_size));
	LOLIX_INTERFACE(set_unif_f	, LOLIX_RETNV	, (size_type idx, const float* in_f, size_type buf_cnt));
	LOLIX_INTERFACE(set_unif_i	, LOLIX_RETNV	, (size_type idx, const int* in_i, size_type buf_cnt));
	LOLIX_INTERFACE(set_tex		, LOLIX_RETNV	, (size_type idx, render_texture*));
};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:材质， 包含 一套渲染环境
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::render_material
	: public itf
{
	LOLIX_DECLARE_ITF(lolix::pretty::render_material, lolix::itf, (0x2b17e9df, 0x3760457b, 0xb4aa0a0f, 0x5003421f));
	LOLIX_INTERFACE(catch_params, LOLIX_RETNV	, (render_params** in_ptr));
	LOLIX_INTERFACE(catch_prop	, LOLIX_RETNV	, (render_properties** out_ptr));
	LOLIX_INTERFACE(get_params	, LOLIX_RETNV	, (const render_params** in_ptr)const);
	LOLIX_INTERFACE(get_prop	, LOLIX_RETNV	, (const render_properties** out_ptr)const);
};

////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:mesh 包含一组格式良好的顶点
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::render_mesh
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::render_mesh, lolix::itf, (0x09c77d53, 0x9a244e88, 0xb5384c72, 0x5528e2fc));
	enum { opt_read = 1, opt_write = 2 };
	enum ENUM_BUFFER_TYPE{BUFFER_TYPE_VERTEX, BUFFER_TYPE_INDEX, _BUFFER_TYPE_CNT, _BUFFER_TYPE_VER = 0};
	enum ENUM_MAPPING_TYPE {MAPPING_TYPE_NULL, MAPPING_TYPE_READ, MAPPING_TYPE_WRITE, MAPPING_TYPE_READ_WRITE};
	enum ENUM_VERTEX_TYPE
	{
		VERTEX_TYPE_UNKNOWS			,	//	未知
		VERTEX_TYPE_POINTS			,	//	点
		VERTEX_TYPE_LINES			,	//	线
		VERTEX_TYPE_STRIP_LINES		,	//	首尾连接的线
		VERTEX_TYPE_LOOP_LINES		,	//	乱七八糟的线
		VERTEX_TYPE_TRIANGLES		,	//	三角形
		VERTEX_TYPE_STRIP_TRIANGLES	,	//	三角条
		VERTEX_TYPE_LOOP_TRIANGLES	,	//	三角形扇（果然还是很乱）

		_VERTEX_TYPE_CNT			,	//
		_VERTEX_TYPE_VER			= 0	//
	};

	struct	mesh_info
	{
		enum {_VER = 2};

		enum { MAX_ATTR_SIZE_POW = 5 };
		enum { VTX_TYPE_SIZE = toy::size_info<_VERTEX_TYPE_CNT - 1>::size_bits };
		enum { IDX_TYPE_BITS_SIZE = lolix::toy::size_info<lolix::_VALUE_TYPE_CNT-1>::size_bits };

		lx_u32	vtx_type	: _VERTEX_TYPE_CNT;		//	这里是什么东西		ENUM_VERTEX_TYPE
		lx_u32	attr_size	: MAX_ATTR_SIZE_POW;	//	有多少个分量呢(比如有顶点数据, 颜色数据, 法线数据, 就是3) 0 == max
		lx_u32	idx_type	: IDX_TYPE_BITS_SIZE;	//	索引的类型是什么:	lolix::ENUM_VALUE_TYPE
	};

	struct	vtx_info
	{
		typedef	lx_u32			value_type;
		enum {_VER = 1, _VT_OFFSET_BITS = 32, _VT_STRIDE_BITS = 16, _VT_SIZE_BITS = 3, _VT_TYPE_BITS = toy::size_info<_VALUE_TYPE_CNT>::size_bits, _VT_SIZE_IDX_BITS = 7};
		value_type	vt_offset	:_VT_OFFSET_BITS;	//	vertex 属性的整体偏移
		value_type	vt_stride	:_VT_STRIDE_BITS;	//	每个元素对齐大小是多少
		value_type	vt_size		:_VT_SIZE_BITS;		//	有多少个分量呢 1, 2, 3, or 4
		value_type	vt_type		:_VT_TYPE_BITS;		//	是什么类型的呢
		value_type	vt_idx		:_VT_SIZE_IDX_BITS;	//	属性的索引值，所绑定的 ID
	};

	struct	buf_info
	{
		typedef lx_u32			value_type;
		enum {_VER = 0, _BF_SIZE_BITS = 32};
		value_type bf_size	: _BF_SIZE_BITS;
		value_type bf_usage	: _USAGE_TYPE_BITS_SIZE;
	};

	//LOLIX_INTERFACE(lock_mesh	, LOLIX_RETNV, (vertex_buffer*, size_type lock_type));
	//LOLIX_INTERFACE(unlock		, LOLIX_RETNV, (const vertex_buffer*));
	LOLIX_INTERFACE(elm_cnt		, LOLIX_RETNV, (size_type* out_size)const);
	LOLIX_INTERFACE(get_binf	, LOLIX_RETNV, (buf_info* inf, ENUM_BUFFER_TYPE buf_type)const);

	LOLIX_INTERFACE(set_minf	, LOLIX_RETNV, (const mesh_info* elm_cnt));
	LOLIX_INTERFACE(get_minf	, LOLIX_RETNV, (mesh_info* elm_cnt)const);

	LOLIX_INTERFACE(set_vinf	, LOLIX_RETNV, (const vtx_info* inf));
	//===========================================================================
	//	取得某个子字段的信息
	//---------------------------------------------------------------------------
	//	inf		[io] :	in. 根据 vt_idx 来判断得哪个属性
	//					o.	输出的信息
	//===========================================================================
	LOLIX_INTERFACE(get_vinf	, LOLIX_RETNV, (vtx_info* inf)const);

	//===========================================================================
	//	设置缓冲区的数据
	//---------------------------------------------------------------------------
	//	dat			[i ] :	数据指针地址, 为空表示不初始化数据
	//	buf_type	[i ] :	缓冲区类型
	//	space_size	[i ] :	申请的数据大小
	//	usage_type	[i ] :	使用的描述数据
	//---------------------------------------------------------------------------
	//	dat 不为0的场合, 其 dat 的实际长度必须大于或者等于 space_size
	//===========================================================================
	LOLIX_INTERFACE(buf_dat		, LOLIX_RETNV, (const void* dat, ENUM_BUFFER_TYPE buf_type, size_type space_size, size_type usage_type));

	//===========================================================================
	//	映射数据到内存中
	//---------------------------------------------------------------------------
	//	buf_ptr		[ o] :	内部数据的返回地址
	//	buf_type	[i ] :	映射哪一个缓冲区
	//	map_type	[i ] :	使用何种权限操作
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(mapping		, LOLIX_RETNV, (void** buf_ptr, ENUM_BUFFER_TYPE buf_type, ENUM_MAPPING_TYPE map_type));

	//===========================================================================
	//	完成映射操作
	//---------------------------------------------------------------------------
	//	buf_ptr		[i ] :	需要解除映射的地址
	//	buf_type	[i ] :	需要解除映射的缓冲区类型
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(unmapping	, LOLIX_RETNV, (const void* buf_ptr, ENUM_BUFFER_TYPE buf_type));


	//===========================================================================
	//	激活缓冲区有效数据长度 : 元素数量
	//---------------------------------------------------------------------------
	//	active_size	[io] :	i)需要激活的长度 o)原始激活的长度
	//---------------------------------------------------------------------------
	//===========================================================================
	LOLIX_INTERFACE(make_active	, LOLIX_RETNV, (size_type* active_size));
};


////////////////////////////////////////////////////////////////////////////
//CLASS>>$	:状态， 包含 一套渲染方法
////////////////////////////////////////////////////////////////////////////
class	LOLIX_NO_VTABLE	lolix::pretty::render_properties
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::render_properties, lolix::itf, (0x1a79b7b7, 0xe4f547e6, 0x98aee46b, 0x94153ad5));
	enum	ENUM_BLEND_FUNC
	{											//	(R, G, B, A)
		BLEND_FUNC_ZERO						,	//	(0, 0, 0, 0)
		BLEND_FUNC_ONE						,	//	(1, 1, 1, 1)
		BLEND_FUNC_SRC_COLOR				,	//	S
		BLEND_FUNC_ONE_MINUS_SRC_COLOR		,	//	1 - S
		BLEND_FUNC_DST_COLOR				,	//	D
		BLEND_FUNC_ONE_MINUS_DST_COLOR		,	//	1 - D
		BLEND_FUNC_SRC_ALPHA				,	//	(As, As, As, As)
		BLEND_FUNC_ONE_MINUS_SRC_ALPHA		,	//	1 - (As, As, As, As)
		BLEND_FUNC_DST_ALPHA				,	//	(Ad, Ad, Ad, Ad)
		BLEND_FUNC_ONE_MINUS_DST_ALPHA		,	//	1 - (Ad, Ad, Ad, Ad)
		BLEND_FUNC_CONSTANT_COLOR			,	//	(C, C, C, C)
		BLEND_FUNC_ONE_MINUS_CONSTANT_COLOR	,	//	1 - (C, C, C, C)
		BLEND_SRC_ALPHA_SATURATE			,	//	(f, f, f, 1) f = min(As, 1-Ad)

		_BLEND_CNT							,
		_BLEND_VER = 0						,
	};

	enum	ENUM_BLEND_EQUATION
	{
		BLEND_EQUATION_ADD				,	//	Cs * S + Cd * D
		BLEND_EQUATION_SUBTRACT			,	//	Cs * S - Cd * D
		BLEND_EQUATION_REVERSE_SUBTRACT	,	//	Cd * D - Cs * S
		BLEND_EQUATION_MIN				,	//	min(Cs, Cd)
		BLEND_EQUATION_MAX				,	//	max(Cs, Cd)

		_BLEND_EQUATION_CNT				,
		_BLEND_EQUATION_VER = 0			,
	};

	enum	ENUM_COMPARE_FUNC
	{
		COMPARE_FUNC_ALWAYS			,
		COMPARE_FUNC_NEVER			,
		COMPARE_FUNC_LESS			,
		COMPARE_FUNC_LESS_EQUAL		,
		COMPARE_FUNC_EQUAL			,
		COMPARE_FUNC_NOT_EQUAL		,
		COMPARE_FUNC_EQUAL_LARGE	,
		COMPARE_FUNC_LARGE			,

		_COMPARE_FUNC_CNT			,
		_COMPARE_FUNC_VER = 1		,
	};

	enum	ENUM_POLYGONMODE_TYPE
	{
		POLYGONMODE_TYPE_FILL	,
		POLYGONMODE_TYPE_LINE	,
		POLYGONMODE_TYPE_POINT	,
		POLYGONMODE_TYPE_NULL	,	//	不渲染
		_POLYGONMODE_TYPE_CNT	,
		_POLYGONMODE_TYPE_VER = 1
	};


__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING()
	typedef	struct	prop_info
	{
		enum	{ _VER = 3 };
		typedef	lolix::lx_u32	flag_type;
		union
		{
			struct
			{
		flag_type	frnt_polyg_mode		: 2;	//	ENUM_POLYGONMODE_TYPE
		flag_type	back_polyg_mode		: 2;
		flag_type	cull_mode			: 2;	//	1 : cull back, 2 : cull front, 3 : cull all, [0] : cull none
		flag_type	_reserve00			:10;
			};

			struct
			{
		flag_type						:16;
		flag_type	depth_test			: 3;	//	ENUM_COMPARE_FUNC default = COMPARE_FUNC_ALWAYS
		flag_type	write_depth			: 1;	//	write to depth buffer.
		flag_type	alpha_blend			: 1;	//	0: no, 1: blend
		flag_type	alpha_to_coverage	: 1;	//	0: off, 1: on	: + by _VER == 3
			};

			struct
			{
		flag_type	all_flag			:22;
		flag_type	_reserve01			:10;
			};

		flag_type	prop_flag;
		};
	}_tagRenderPropBase;
	STATIC_ASSERT(sizeof(_tagRenderPropBase) == 4);

//#pragma	pack(push, 4)
	//	如果 blend 开启
	typedef struct prop_info_blend
		: public _tagRenderPropBase
	{
		typedef _tagRenderPropBase::flag_type flag_type;
		union
		{
			struct
			{
		flag_type	blend_src_rgb	: 4;	//	ENUM_BLEND_FUNC
		flag_type	blend_src_a		: 4;
		flag_type	blend_dst_rgb	: 4;
		flag_type	blend_dst_a		: 4;
		flag_type	blend_equ_rgb	: 3;	//	ENUM_BLEND_EQUATION
		flag_type	blend_equ_a		: 3;	//	ENUM_BLEND_EQUATION
			};
		flag_type	blend_mask;
		};

		float	blend_const[4];	//	附加数据
	}_tagRenderPropWithAlphaBlend;
	STATIC_ASSERT(sizeof(_tagRenderPropWithAlphaBlend) == 4*6);
__END_DISABLE_NO_NAME_STRUCT_WARNING()

//#pragma	pack(pop)

	//===========================================================================
	//	加载某段 shader
	//---------------------------------------------------------------------------
	//	sd		[i ] :	需要加载的 shader
	//	alink	[i ] :	true) 当加载的 shader 更新时, 自动重新 link shader.
	//					false)不监视指定的 shader 的更新.
	//===========================================================================
	LOLIX_INTERFACE(attach	, LOLIX_RETNV		, (const render_shader* sd, bool alink));

	//===========================================================================
	//	卸载某段 shader
	//---------------------------------------------------------------------------
	//	sd		[i ] :	需要卸载的 shader, 如果为空则表示卸载全部
	//===========================================================================
	LOLIX_INTERFACE(dettach	, LOLIX_RETNV		, (const render_shader*));

	LOLIX_INTERFACE(link	, LOLIX_RETNV		, (void));

	LOLIX_INTERFACE(set_prop, LOLIX_RETNV		, (const prop_info*));
	LOLIX_INTERFACE(get_prop, const prop_info*	, (void)const);
};


class	LOLIX_NO_VTABLE lolix::pretty::render_shader
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::render_shader, lolix::itf, (0xead593cf, 0x188f438e, 0x837a5fe4, 0x4b8a3cef));
	LOLIX_INTERFACE(compile	, LOLIX_RETNV		, (const char* const, size_type sslen, ENUM_SHADER_TYPE ss_type));
	LOLIX_INTERFACE(get_type, LOLIX_RETNV		, (ENUM_SHADER_TYPE* ss_type)const);
};



class	LOLIX_NO_VTABLE	lolix::pretty::render_texture
	: public itf
{
public:
	LOLIX_DECLARE_ITF(lolix::pretty::render_texture, lolix::itf, (0x068dc718, 0x0111491f, 0xaa5551a8, 0x33763d3b));
	enum TEX_TGT
	{
		t_xd	,	//	未知纹理属性
		t_1d	,
		t_2d	,
		t_3d	,
		t_cube	,

		t_cnt	,	//	计数
		t_ver = 0,	//	枚举版本
	};

	enum	ENUM_WRAP_TYPE
	{
		WRAP_REPEAT				,
		//WRAP_CLAMP				,
		WRAP_MIRRORED_REPEAT	,
		WRAP_CLAMP_TO_EDGE		,
		WRAP_CLAMP_TO_BORDER	,
		WRAP_TYPE_CNT			,
		WRAP_TYPE_VER		= 2,
	};

	enum	ENUM_FILTER_TYPE
	{
		FILTER_NEAREST					,
		FILTER_LINEAR					,
		FILTER_NEAREST_MIPMAP_NEAREST	,
		FILTER_NEAREST_MIPMAP_LINEAR	,
		FILTER_MIPMAP_LINEAR			,

		FILTER_TYPE_CNT					,
		FILTER_TYPE_VER	= 0				,
	};

#pragma	pack(push, 4)
	typedef	struct	tex_cfg
	{
__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
		enum { _VER = 2 };
		union
		{
			struct{
		lx_u32	have_flag	: 8;
		lx_u32				: 8;

		lx_u32	mip_min		: 4;	//	用于 min 的最小 lod 数
		lx_u32	mip_max		: 4;	//	用于 min 的最大 lod 数
		//lx_u32	load_min	: 4;	//	载入的最小 lod
		//lx_u32	load_max	: 4;	//	载入的最大 lod
			};
			struct{
		lx_u32	have_anis	: 1;
		lx_u32	have_filter	: 1;
		//lx_u32	have_load	: 1;
		lx_u32	have_mip	: 1;
		lx_u32	have_wrap	: 1;
			};
		lx_u32	cfg_flag	: 32;
		};
		//	32 bits

		lx_u32	tx_anis		: 5;	//	anisotropy_level
		lx_u32	tx_tgt		: 3;	//	是什么类型的 Texture? : TEX_TGT
		lx_u32	filter_min	: 3;
		lx_u32	filter_mag	: 3;


		lx_u32	wrap_s		: 3;	//	WRAP_TYPE
		lx_u32	wrap_t		: 3;	//	WRAP_TYPE
		lx_u32	wrap_r		: 3;	//	WRAP_TYPE
		lx_u32				: 9;	//

__END_DISABLE_NO_NAME_STRUCT_WARNING();
	}_tagTextureCfg;
	STATIC_ASSERT(sizeof(tex_cfg) == 8);


	typedef struct	tex_level_data
	{
		enum {_VER = 0};

		lx_u32	x	:16;	//
		lx_u32	y	:16;	//

		lx_u32	z	:16;	//
		lx_u32	w	:16;	//	多宽

		lx_u32	h	:16;	//	多高
		lx_u32	d	:16;	//	多厚

		lx_u32	tx_fmt	: 4;	//	PIXEL_TYPE
		lx_u32	tx_type	: 4;	//	ELEMENT_TYPE
	}_tagTexLevelData;

#pragma	pack(pop)

	LOLIX_INTERFACE(new_tex	, LOLIX_RETNV, (const tex_cfg* in_ptr));
	LOLIX_INTERFACE(get_cfg	, LOLIX_RETNV, (tex_cfg* out_ptr)const);
	LOLIX_INTERFACE(set_data, LOLIX_RETNV, (tex_level_data const* sub_img, lolix::size_type lod_lev, bool fill_sub, const void* ptr));
	LOLIX_INTERFACE(get_data, LOLIX_RETNV, (const tex_level_data* sub_img, lolix::size_type lod_lev, void* ptr)const);
	LOLIX_INTERFACE(get_ldat, LOLIX_RETNV, (tex_level_data* sub_img, lolix::size_type lod_lev)const);
};



//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX__PRETTY__CANVAS__K_IN_G__)
